package main

import (
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql" // 加上前缀 "_" 表示只是用到它内部的一些初始化的方法
)

//gorm demo05 修改

// PersonInfo 1.定义模型
type PersonInfo struct {
	gorm.Model
	Name   string
	Age    int64
	Active bool
}

func main() {
	//2.连接 MySQL 数据库
	db, err := gorm.Open("mysql", "root:123456@(127.0.0.1:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic(err)
	}
	defer db.Close()

	//3.把模型与数据库中的表对应起来
	db.AutoMigrate(&PersonInfo{})

	// 4.创建
	//p1 := PersonInfo{Name: "htl", Age: 36, Active: true}
	//db.Create(&p1)
	//p2 := PersonInfo{Name: "swk", Age: 500, Active: false}
	//db.Create(&p2)

	//5.查询
	var p PersonInfo
	db.First(&p)
	fmt.Printf("%#v\n", p)
	//main.PersonInfo{Model:gorm.Model{ID:0x1, CreatedAt:time.Date(2023, time.August, 31, 9, 29, 45, 0, time.Local), UpdatedAt:time.Date(2023, time.August, 31, 9, 32, 28, 0, time.Local), DeletedAt:<nil>}, Name:"xtl", Age:36, Active:true}

	////6.更新
	//p.Name = "xhh"
	//p.Age = 7
	//db.Save(&p) //默认会修改所有字段
	//fmt.Printf("%#v\n", p)
	////main.PersonInfo{Model:gorm.Model{ID:0x1, CreatedAt:time.Date(2023, time.August, 31, 9, 29, 45, 0, time.Local), UpdatedAt:time.Date(2023, time.August, 31, 9, 32, 59, 829722100, time.Local), DeletedAt:<nil>}, Name:"xhh", Age:7, Active:true}
	//
	////更新单个属性
	//db.Model(&p).Update("name", "狼")
	//fmt.Printf("%#v\n", p)
	////main.PersonInfo{Model:gorm.Model{ID:0x1, CreatedAt:time.Date(2023, time.August, 31, 9, 29, 45, 0, time.Local), UpdatedAt:time.Date(2023, time.August, 31, 9, 36, 6, 708020200, time.Local), DeletedAt:<nil>}, Name:"狼", Age:7, Active:true}

	//更新多个属性
	/*
		1.当使用 struct 进行更新时，只会更新非零字段
		  使用 map 进行更新时，可以更新那些 值为零 的字段
		2.默认更新 struct 或 map 所列出的所有字段
	*/
	//db.Model(&p).Updates(PersonInfo{Name: "hhh", Age: 20})
	//fmt.Printf("%#v\n", p)
	////main.PersonInfo{Model:gorm.Model{ID:0x1, CreatedAt:time.Date(2023, time.August, 31, 9, 29, 45, 0, time.Local), UpdatedAt:time.Date(2023, time.August, 31, 9, 49, 36, 439776400, time.Local), DeletedAt:<nil>}, Name:"hhh", Age:20, Active:true}
	//
	//db.Model(&p).Updates(map[string]interface{}{"name": "xix", "age": 3})
	//fmt.Printf("%#v\n", p)
	////main.PersonInfo{Model:gorm.Model{ID:0x1, CreatedAt:time.Date(2023, time.August, 31, 9, 29, 45, 0, time.Local), UpdatedAt:time.Date(2023, time.August, 31, 9, 49, 36, 442040800, time.Local), DeletedAt:<nil>}, Name:"xix", Age:3, Active:true}

	/*
		3.在使用 Updates() 时，更新指定的字段 可以使用 Select() 函数
	*/
	db.Model(&p).Select("name").Updates(map[string]interface{}{"name": "天", "age": 3})
	fmt.Printf("%#v\n", p)
	//main.PersonInfo{Model:gorm.Model{ID:0x1, CreatedAt:time.Date(2023, time.August, 31, 9, 29, 45, 0, time.Local), UpdatedAt:time.Date(2023, time.August, 31, 9, 54, 52, 14895800, time.Local), DeletedAt:<nil>}, Name:"天", Age:3, Active:true}

	/*
		4.在使用 Updates 时，忽略指定的字段，更新其他的字段 可以使用 Omit() 函数
	*/
	db.Model(&p).Omit("active").Updates(PersonInfo{Name: "天天", Age: 10, Active: false})
	fmt.Printf("%#v\n", p)
	//main.PersonInfo{Model:gorm.Model{ID:0x1, CreatedAt:time.Date(2023, time.August, 31, 9, 29, 45, 0, time.Local), UpdatedAt:time.Date(2023, time.August, 31, 13, 15, 1, 832696300, time.Local), DeletedAt:<nil>}, Name:"天", Age:10, Active:true}

	/*
		5.UpdateColumn(): 更新单个属性，类似于 Update
	*/
	db.Model(&p).UpdateColumn("name", "hello")
	fmt.Printf("%#v\n", p)

	/*
		6.UpdateColumns(): 更新多个属性，类似于 Updates
	*/
	db.Model(&p).UpdateColumn(PersonInfo{Name: "xyy", Active: false})
	fmt.Printf("%#v\n", p)

	/*
		7.批量更新，Host(钩子函数)不会运行
		8.rowsAffected： 获取更新记录数
	*/
	rowsAffected := db.Model(PersonInfo{}).Updates(PersonInfo{Name: "hello", Age: 18}).RowsAffected
	// UPDATE users SET name='hello', age=18;
	fmt.Printf("rowsAffected:%#v\n", rowsAffected)

	/*
		9.使用 SQL 表达式更新 gorm.Expr()
	*/
	db.Model(&p).Update("age", gorm.Expr("age - ?", 10))
	db.Model(PersonInfo{}).Updates(map[string]interface{}{"age": gorm.Expr("age * ? + ?", 2, 100)})

}
